import PlatformsList from '../../components/PlatformsList/PlatformsList.tsx';

# Configurable Props

This page shows the list of available properties to configure the player.

## Details

### `adTagUrl`

> [!WARNING]
> Deprecated, use `source.ad.adTagUrl` instead.

<PlatformsList types={['Android', 'iOS']} />

Sets the VAST URI to play AVOD ads.

**Example:**

```javascript
adTagUrl="https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator="
```

> **Note:** You need to enable IMA SDK in the Gradle or Podfile – see [Enable Client-Side Ads Insertion](/installation).

---

### `allowsExternalPlayback`

<PlatformsList types={['iOS']} />

Indicates whether the player allows switching to external playback mode such as AirPlay or HDMI.

- **true (default)** – Allows switching to external playback mode.
- **false** – Prevents switching to external playback mode.

---

### `audioOutput`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Changes the audio output.

- **speaker (default)** – Plays through the speaker.
- **earpiece** – Plays through the earpiece.

---

### `automaticallyWaitsToMinimizeStalling`

<PlatformsList types={['iOS', 'visionOS']} />

Indicates whether the player should automatically delay playback to minimize stalling. Available for clients linked against iOS 10.0 and later.

- **false** – Immediately starts playback.
- **true (default)** – Delays playback to minimize stalling.

---

### `bufferConfig`

> [!WARNING]
> Deprecated, use `source.bufferConfig` instead.

<PlatformsList types={['Android']} />

Adjusts the buffer settings. This prop takes an object with one or more of the following properties:

| Property                         | Type   | Description                                                                                   |
|----------------------------------|--------|-----------------------------------------------------------------------------------------------|
| minBufferMs                      | number | Minimum duration (ms) the player will attempt to keep buffered.                             |
| maxBufferMs                      | number | Maximum duration (ms) the player will attempt to buffer.                                   |
| bufferForPlaybackMs              | number | Duration (ms) that must be buffered before playback starts or resumes.                      |
| bufferForPlaybackAfterRebufferMs | number | Duration (ms) that must be buffered after a rebuffer before playback resumes.              |
| backBufferDurationMs             | number | Duration (ms) of buffer to keep before the current position (allows rewinding).            |
| maxHeapAllocationPercent         | number | Percentage of available heap the video can use to buffer (0 to 1).                          |
| minBackBufferMemoryReservePercent| number | Percentage of available app memory before the back buffer is disabled (0 to 1).            |
| minBufferMemoryReservePercent    | number | Percentage of available app memory reserved for preventing buffer usage (0 to 1).          |
| cacheSizeMB                      | number | Cache size in MB. Set to `0` to disable caching (Android only).                            |
| live                             | object | Object containing configuration for live playback. See below.                              |

#### Live Buffer Configurations

| Property         | Type   | Description                                                                 |
|-----------------|--------|-----------------------------------------------------------------------------|
| maxPlaybackSpeed| number | Maximum playback speed for catching up to target live offset.              |
| minPlaybackSpeed| number | Minimum playback speed for falling back to target live offset.             |
| maxOffsetMs     | number | Maximum allowed live offset. The player won’t exceed this limit.           |
| minOffsetMs     | number | Minimum allowed live offset. The player won’t go below this limit.         |
| targetOffsetMs  | number | The target live offset the player will aim to maintain.                    |

For more details on Android live streaming, see [ExoPlayer Live Streaming](https://developer.android.com/media/media3/exoplayer/live-streaming?hl=en).

#### Example with Default Values

```javascript
bufferConfig={{
  minBufferMs: 15000,
  maxBufferMs: 50000,
  bufferForPlaybackMs: 2500,
  bufferForPlaybackAfterRebufferMs: 5000,
  backBufferDurationMs: 120000,
  cacheSizeMB: 0,
  live: {
      targetOffsetMs: 500,
  },
}}
```

> **Note:** The Android cache is global and shared among all components. The first `cacheSizeMB` value set persists throughout the app lifecycle.

---

### `bufferingStrategy`

<PlatformsList types={['Android']} />

Configures the buffering and data loading strategy.

- **Default (default)** – Uses ExoPlayer's default loading strategy.
- **DisableBuffering** – Prevents buffering beyond the immediate need. **Use with caution, as this may stop playback.**
- **DependingOnMemory** – Uses ExoPlayer’s default strategy but stops buffering and triggers garbage collection when memory is low.

---

### `chapters`

<PlatformsList types={['tvOS']} />

Provides a custom chapter source for tvOS. This prop takes an array of objects with the following properties:

| Property  | Type    | Description                                                                 |
|----------|--------|-----------------------------------------------------------------------------|
| title    | string  | The title of the chapter.                                                  |
| startTime| number  | The start time of the chapter (seconds).                                  |
| endTime  | number  | The end time of the chapter (seconds).                                    |
| uri      | string? | Optional image override URL (HTTP or Base64). Some media auto-generate images. |

---

### `currentPlaybackTime`

<PlatformsList types={['Android', 'iOS']} />

When playing an HLS live stream with an `EXT-X-PROGRAM-DATE-TIME` tag, this property contains the epoch value in milliseconds.

---

### `controls`

<PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />

Determines whether player controls are shown.

- **false (default)** – Hides player controls.
- **true** – Displays player controls.

Controls are always visible in fullscreen mode, even if `controls={false}`. To add custom controls, use packages like:

- [react-native-video-controls](https://github.com/itsnubix/react-native-video-controls)
- [react-native-media-console](https://github.com/criszz77/react-native-media-console)

See [Useful Side Projects](/projects).

---

### `controlsStyles`

<PlatformsList types={['Android']} />

Adjust the control styles. This prop is needed only if `controls={true}` and is an object. See the supported properties below.

| Property                            | Type    | Description                                                                                 |
|-------------------------------------|---------|---------------------------------------------------------------------------------------------|
| hidePosition                        | boolean | Hides the position indicator. Default is `false`.                                           |
| hidePlayPause                       | boolean | Hides the play/pause button. Default is `false`.                                            |
| hideForward                         | boolean | Hides the forward button. Default is `false`.                                               |
| hideRewind                          | boolean | Hides the rewind button. Default is `false`.                                                |
| hideNext                            | boolean | Hides the next button. Default is `false`.                                                  |
| hidePrevious                        | boolean | Hides the previous button. Default is `false`.                                              |
| hideFullscreen                      | boolean | Hides the fullscreen button. Default is `false`.                                            |
| hideSeekBar                         | boolean | Hides the seek bar, useful for live broadcasts. Default is `false`.                         |
| hideDuration                        | boolean | Hides the duration display. Default is `false`.                                             |
| hideNavigationBarOnFullScreenMode   | boolean | Hides the navigation bar in fullscreen mode. Default is `true`.                             |
| hideNotificationBarOnFullScreenMode | boolean | Hides the notification bar in fullscreen mode. Default is `true`.                           |
| hideSettingButton                   | boolean | Hides the settings button. Default is `true`.                                               |
| seekIncrementMS                     | number  | Defines the seek increment in milliseconds. Default is `10000`.                             |
| liveLabel                           | string  | Sets a label for live video.                                                                |

**Example with default values:**

```javascript
controlsStyles={{
  hidePosition: false,
  hidePlayPause: false,
  hideForward: false,
  hideRewind: false,
  hideNext: false,
  hidePrevious: false,
  hideFullscreen: false,
  hideSeekBar: false,
  hideDuration: false,
  hideNavigationBarOnFullScreenMode: true,
  hideNotificationBarOnFullScreenMode: true,
  hideSettingButton: true,
  seekIncrementMS: 10000,
  liveLabel: "LIVE"
}}
```

---

### `contentStartTime`

> [!WARNING]
> Deprecated, use `source.contentStartTime` instead.

<PlatformsList types={['Android']} />

Defines the start time in milliseconds for SSAI content. This ensures that video resolutions are loaded at the correct time. **Note:** This feature only works with DASH streams.

---

### `debug`

<PlatformsList types={['Android']} />

Enables detailed logging.

> [!WARNING]
> Do not use this in production builds.

| Property | Type    | Description                                  |
| -------- | ------- | -------------------------------------------- |
| `enable` | boolean | Enables verbose logs. Default is `false`.    |
| `thread` | boolean | Displays logs with thread information.       |

**Example:**

```javascript
debug={{
  enable: true,
  thread: true,
}}
```

---

### `disableFocus`

<PlatformsList types={['Android']} />

Determines whether video audio should override background music/audio on Android.

- **false (default)** – Overrides background audio/music.
- **true** – Allows background audio/music from other apps to continue playing.

> **Note:** If `true`, multiple videos can play simultaneously. If `false`, starting another video will pause the first one.

---

### `disableDisconnectError`

<PlatformsList types={['Android']} />

Determines if the player should throw an error when the network connection is lost.

- **false (default)** – Throws an error when the connection is lost.
- **true** – The player will keep trying to buffer when the connection is lost.

---

### `disableAudioSessionManagement`

<PlatformsList types={['iOS']} />

Disable audio session management in library (for all views).

- **true** - Disable audio session management in the library.
- **false (default)** - Enable audio session management in the library.

> ⚠️ This prop disables audio session management in the library. You only should use this prop if you are managing the audio session yourself.
> You can encounter issues with other features, like background audio, if you don't properly manage the audio session.

---

### `drm`

> [!WARNING]
> Deprecated, use `source.drm` instead.

<PlatformsList types={['Android', 'iOS']} />

To set up DRM, follow [this guide](/component/drm).

---

### `enterPictureInPictureOnLeave`

<PlatformsList types={['iOS', 'Android']} />

Determines whether to enter Picture-in-Picture (PiP) mode when the user leaves the app.

- **false (default)** – Does not enable PiP mode.
- **true** – Plays media in PiP mode when the user switches apps.

**Using this on Android:**

- **With Expo:** Add `enableAndroidPictureInPicture` to `app.json`:

```json
  "plugins": [
    [
      "react-native-video",
      {
        "enableAndroidPictureInPicture": true
      }
    ]
  ]
```

- **With Bare React Native:** Add PiP support in `AndroidManifest.xml`:

```xml
<activity
  android:name=".MainActivity"
  android:supportsPictureInPicture="true">
```

> **Note:** Video ads cannot start when using PiP on iOS. More details are available in the [Google IMA SDK Docs](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/picture_in_picture?hl=en#starting_ads).

---

### `filter`

<PlatformsList types={['iOS', 'visionOS']} />

Applies a video filter.

| FilterType                  | Description             |
|-----------------------------|-------------------------|
| `NONE (default)`            | No filter               |
| `INVERT`                    | CIColorInvert           |
| `MONOCHROME`                | CIColorMonochrome       |
| `POSTERIZE`                 | CIColorPosterize        |
| `FALSE`                     | CIFalseColor            |
| `MAXIMUMCOMPONENT`          | CIMaximumComponent      |
| `MINIMUMCOMPONENT`          | CIMinimumComponent      |
| `CHROME`                    | CIPhotoEffectChrome     |
| `FADE`                      | CIPhotoEffectFade       |
| `INSTANT`                   | CIPhotoEffectInstant    |
| `MONO`                      | CIPhotoEffectMono       |
| `NOIR`                      | CIPhotoEffectNoir       |
| `PROCESS`                   | CIPhotoEffectProcess    |
| `TONAL`                     | CIPhotoEffectTonal      |
| `TRANSFER`                  | CIPhotoEffectTransfer   |
| `SEPIA`                     | CISepiaTone             |

> **Notes:**
> 1. Using a filter may increase CPU usage.
> 2. Saving a filtered video and reloading it is a workaround for performance issues.
> 3. Filters are not supported on HLS playlists.
> 4. `filterEnabled` must be set to `true` for filters to work.

---

### `filterEnabled`

<PlatformsList types={['iOS', 'visionOS']} />

Enables video filter.

- **false (default)** – Don't enable filter.
- **true** – Enable filter.

---

### `focusable`

<PlatformsList types={['Android']} />

Determines whether this video view should be focusable with a non-touch input device, such as a hardware keyboard.

- **false** – Makes view unfocusable.
- **true (default)** – Makes view focusable.

---

### `fullscreen`

<PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />

Controls whether the player enters fullscreen on play.

- **false (default)** – Don’t display the video in fullscreen.
- **true** – Display the video in fullscreen.

See [presentFullscreenPlayer](#presentfullscreenplayer) for details.

---

### `fullscreenAutorotate`

<PlatformsList types={['iOS', 'visionOS']} />

If a preferred [fullscreenOrientation](#fullscreenorientation) is set, this causes the video to rotate to that orientation but permits rotation of the screen to match the user's holding position. Defaults to `true`.

---

### `fullscreenOrientation`

<PlatformsList types={['iOS', 'visionOS', 'web']} />

- **all (default)** – Allows rotation in all orientations.
- **landscape** – Locks fullscreen to landscape mode.
- **portrait** – Locks fullscreen to portrait mode.

---

### `headers`

<PlatformsList types={['iOS', 'Android']} />

Passes headers to the HTTP client, which can be used for authorization. Headers must be part of the source object.

**Example:**

```javascript
source={{
  uri: "https://www.example.com/video.mp4",
  headers: {
    Authorization: 'Bearer some-token-value',
    'X-Custom-Header': 'some value'
  }
}}
```

---

### `hideShutterView`

<PlatformsList types={['Android']} />

Controls whether the ExoPlayer shutter view (black screen while loading) is enabled.

- **false (default)** – Show shutter view.
- **true** – Hide shutter view.

---

### `ignoreSilentSwitch`

<PlatformsList types={['iOS', 'visionOS']} />

Controls the iOS silent switch behavior.

- **"inherit" (default)** – Uses the default AVPlayer behavior.
- **"ignore"** – Plays audio even if the silent switch is set.
- **"obey"** – Doesn’t play audio if the silent switch is set.

---

### `maxBitRate`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Sets the desired limit, in bits per second, of network bandwidth consumption when multiple video streams are available for a playlist.

**Default:** `0` (no limit on maxBitRate).

**Example:**

```javascript
maxBitRate={2000000} // 2 megabits
```

---

### `mixWithOthers`

<PlatformsList types={['iOS', 'visionOS']} />

Controls how audio mixes with other apps.

- **"inherit" (default)** – Uses the default AVPlayer behavior.
- **"mix"** – Allows this video’s audio to mix with other apps.
- **"duck"** – Lowers the volume of other apps while playing this video.

---

### `muted`

<PlatformsList types={['All']} />

Controls whether the audio is muted.

- **false (default)** – Don’t mute audio.
- **true** – Mute audio.

---

### `paused`

<PlatformsList types={['All']} />

Controls whether the media is paused.

- **false (default)** – Don’t pause the media.
- **true** – Pause the media.

---

### `playInBackground`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Determines whether the media should continue playing while the app is in the background.

- **false (default)** – Don’t continue playing the media.
- **true** – Continue playing the media.

To use this feature on iOS, you must:

- [Enable Background Audio](https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionBasics/AudioSessionBasics.html#//apple_ref/doc/uid/TP40007875-CH3-SW3) in your Xcode project.
- Set the `ignoreSilentSwitch` prop to "ignore".

---

### `playWhenInactive`

<PlatformsList types={['iOS', 'visionOS']} />

Determines whether the media should continue playing when notifications or the Control Center are in front of the video.

- **false (default)** – Don’t continue playing the media.
- **true** – Continue playing the media.

---

### `poster`

<PlatformsList types={['All']} />

> [!WARNING]
> Value: string with a URL for the poster is deprecated, use `poster` as an object instead.

An image to display while the video is loading.

**Example:**

```javascript
<Video>
  poster={{
    source: { uri: "https://baconmockup.com/300/200/" },
    resizeMode: "cover",
  }}
</Video>
```

---

### `posterResizeMode`

> [!WARNING]
> Deprecated, use `poster` with `resizeMode` key instead.

<PlatformsList types={['All']} />

Determines how to resize the poster image when the frame doesn’t match the raw video dimensions.

- **"contain" (default)** – Scales the image uniformly to fit within the view.
- **"center"** – Centers the image in the view without scaling beyond its original size.
- **"cover"** – Scales the image uniformly, ensuring it fills the view while maintaining aspect ratio.
- **"none"** – No resizing applied.
- **"repeat"** – Repeats the image to fill the view (iOS only).
- **"stretch"** – Stretches width and height independently, potentially distorting the aspect ratio.

---

### `preferredForwardBufferDuration`

<PlatformsList types={['iOS', 'visionOS']} />

Defines how long the player should buffer media ahead of the playhead to prevent playback interruptions.

**Default:** `0`.

[Apple Documentation](https://developer.apple.com/documentation/avfoundation/avplayeritem/1643630-preferredforwardbufferduration)

---

### `preventsDisplaySleepDuringVideoPlayback`

<PlatformsList types={['iOS', 'Android']} />

Determines whether the device screen should remain active while playing a video.

**Default:** `true` (prevents the display from sleeping).

---

### `progressUpdateInterval`

<PlatformsList types={['All']} />

Sets the delay (in milliseconds) between `onProgress` events.

**Default:** `250.0` ms.

---

### `rate`

<PlatformsList types={['All']} />

Controls the speed at which the media should play.

- **0.0** – Pauses the video (iOS only).
- **1.0 (default)** – Plays at normal speed.
- **Other values** – Adjusts playback speed (faster/slower).

---

### `renderLoader`

<PlatformsList types={['All']} />

Allows you to provide a custom component to display while the video is loading.

If `renderLoader` is provided, `poster` and `posterResizeMode` will be ignored.

`renderLoader` can be either a component or a function returning a component.

#### Function Signature

```typescript
interface ReactVideoRenderLoaderProps {
  source?: ReactVideoSource;
  style?: StyleProp<ImageStyle>;
  resizeMode?: EnumValues<VideoResizeMode>;
}
```

#### Example

```javascript
<Video>
  renderLoader={() => (
    <View>
      <Text>Custom Loader</Text>
    </View>
  )}
</Video>
```

---

### `repeat`

<PlatformsList types={['All']} />

Determines whether to repeat the video when playback reaches the end.

- **false (default)** – Don’t repeat the video.
- **true** – Repeat the video.

---

### `reportBandwidth`

<PlatformsList types={['Android']} />

Determines whether to generate `onBandwidthUpdate` events. This is necessary due to the high frequency of these events on ExoPlayer.

- **false (default)** – Don’t generate `onBandwidthUpdate` events.
- **true** – Generate `onBandwidthUpdate` events.

---

### `resizeMode`

<PlatformsList types={['Android', 'iOS', 'Windows UWP']} />

Determines how to resize the video when the frame doesn’t match the raw video dimensions.

- **"none" (default)** – No resizing applied.
- **"contain"** – Scales the video uniformly to fit within the view.
- **"cover"** – Scales the video uniformly to fill the view while maintaining aspect ratio.
- **"stretch"** – Stretches width and height independently, which may alter the aspect ratio.

---

### `selectedAudioTrack`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Configures which audio track, if any, is played.

```javascript
selectedAudioTrack={{
  type: "title",
  value: "Dubbing"
}}
```

| Type               | Value  | Description                                                                                 |
| ------------------ | ------ | ------------------------------------------------------------------------------------------- |
| "system" (default) | N/A    | Play the audio track that matches the system language. If none match, play the first track. |
| "disabled"         | N/A    | Turn off audio.                                                                             |
| "title"            | string | Play the audio track with the specified title, e.g., "French".                            |
| "language"         | string | Play the audio track with the specified language, e.g., "fr".                              |
| "index"            | number | Play the audio track with the specified index, e.g., 0.                                     |

If no matching track is found, the first available track will be played. If multiple tracks match, the first match will be used.

---

### `selectedTextTrack`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Configures which text track (captions or subtitles), if any, is shown.

```javascript
selectedTextTrack={{
  type: "title",
  value: "English Subtitles"
}}
```

| Type               | Value  | Description                                                                   |
| ------------------ | ------ | ----------------------------------------------------------------------------- |
| "system" (default) | N/A    | Display captions only if the system preference for captions is enabled.       |
| "disabled"         | N/A    | Don’t display a text track.                                                   |
| "title"            | string | Display the text track with the specified title, e.g., "French 1".          |
| "language"         | string | Display the text track with the specified language, e.g., "fr".             |
| "index"            | number | Display the text track with the specified index, e.g., 0.                     |

If no matching track is found, no subtitles will be displayed. If multiple tracks match, the first match will be used.

---

### `selectedVideoTrack`

<PlatformsList types={['Android']} />

Configures which video track should be played. By default, the player uses Adaptive Bitrate Streaming (ABR) to automatically select the best stream based on available bandwidth.

```javascript
selectedVideoTrack={{
  type: "resolution",
  value: 480
}}
```

| Type             | Value  | Description                                                                  |
| ---------------- | ------ | ---------------------------------------------------------------------------- |
| "auto" (default) | N/A    | Let the player determine the best track using ABR.                           |
| "disabled"       | N/A    | Turn off video.                                                               |
| "resolution"     | number | Play the video track with the specified height, e.g., 480 for the 480p stream. |
| "index"          | number | Play the video track with the specified index, e.g., 0.                       |

If no matching track is found, ABR will be used.

---

### `shutterColor`

<PlatformsList types={['Android']} />

Applies color to the shutter view. If black flashes appear before the video starts, set:

```javascript
shutterColor = 'transparent';
```

**Default:** `black`.

---

### `source`

Sets the media source. You can pass an asset loaded via `require` or an object with a `uri`.

Setting the source will trigger the player to attempt to load the provided media with all other given props. Ensure all props are provided before or at the same time as setting the source.

Rendering the player component with a `null` source initializes the player and starts playing once a source value is provided.

Providing a `null` source value after loading a previous source stops playback and clears out the previous content.

The documentation for this prop is incomplete and will be updated as each option is investigated and tested.

#### Asset Loaded via `require`

> ⚠️ On iOS, file names must not contain spaces. For example, `my video.mp4` will not work—use `my-video.mp4` instead.

<PlatformsList types={['Android', 'iOS', 'visionOS', 'Windows UWP']} />

Example:

Pass the asset directly (deprecated):

```javascript
const sintel = require('./sintel.mp4');
source = { sintel };
```

Or by using a URI (starting from `6.0.0-beta.6`):

```javascript
const sintel = require('./sintel.mp4');
source={{ uri: sintel }}
```

#### URI String

A number of URI schemes are supported by passing an object with a `uri` attribute.

All URI strings must be URL encoded.
For example, `'www.myurl.com/blabla?q=test uri'` is invalid, whereas `'www.myurl.com/blabla?q=test%20uri'` is valid.

##### Web Address (`http://`, `https://`)

<PlatformsList types={['All']} />

Example:

```javascript
source={{ uri: 'https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4' }}
```

##### File Path (`file://`)

<PlatformsList types={['Android']} />

Example:

```javascript
source={{ uri: 'file:///sdcard/Movies/sintel.mp4' }}
```

Note: Your app will need permission to read external storage if accessing a file outside your app.

##### File from Asset Folder (`asset://`)

<PlatformsList types={['Android']} />

Allows playing a video file from the app's asset folder.

Example:

```javascript
source={{ uri: 'asset:///sintel.mp4' }}
```

##### iPod Library (`ipod-library://`)

<PlatformsList types={['iOS']} />

Path to a sound file in your iTunes library, typically shared from iTunes to your app.

Example:

```javascript
source={{ uri: 'ipod-library:///path/to/music.mp3' }}
```

Note: Using this feature requires adding an entry for `NSAppleMusicUsageDescription` to your `Info.plist` file, as described [here](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html).

##### Explicit MIME Type for Streams

Provide a `type` property (`mpd`/`m3u8`/`ism`) inside the source object.
This is needed when the URL extension does not match the expected MIME type.

Example (URL extension is `.ism` for Smooth Streaming, but the file is actually MPEG-DASH (`mpd`)):

```javascript
source={{ uri: 'http://host-serving-a-type-different-than-the-extension.ism/manifest(format=mpd-time-csf)',
type: 'mpd' }}
```

##### Other Protocols

The following protocols are supported on some platforms but not fully documented yet:
`content://, ms-appx://, ms-appdata://, assets-library://`

#### Using DRM Content

<PlatformsList types={['Android', 'iOS', 'visionOS', 'tvOS']} />

To set up DRM, follow [this guide](/component/drm).

Example:

```javascript
{
  description: 'WV: Secure SD & HD (cbcs, MP4, H264)',
  uri: 'https://storage.googleapis.com/wvmedia/cbcs/h264/tears/tears_aes_cbcs.mpd',
  drm: {
    type: DRMType.WIDEVINE,
    licenseServer:
      'https://proxy.uat.widevine.com/proxy?provider=widevine_test',
  },
},
```

#### Start Playback at a Specific Point in Time

<PlatformsList types={['Android', 'iOS', 'web']} />

Provide an optional `startPosition` for video playback. The value is in milliseconds. If the `cropStart` prop is applied, it will be applied from that point forward.
(If it is negative, undefined, or `null`, it is ignored.)

#### Playing Only a Portion of the Video (Start & End Time)

<PlatformsList types={['Android', 'iOS']} />

Provide an optional `cropStart` and/or `cropEnd` for the video. Values are in milliseconds. This is useful when you want to play only a portion of a large video.

**Example:**

```javascript
source={{ uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8', cropStart: 36012, cropEnd: 48500 }}

source={{ uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8', cropStart: 36012 }}

source={{ uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8', cropEnd: 48500 }}
```

#### Overriding the Metadata of a Source

<PlatformsList types={['Android', 'iOS', 'tvOS']} />

Provide optional `title`, `subtitle`, `artist`, `imageUri`, and/or `description` properties for the video.
This is useful when using notification controls on Android or iOS or adapting the tvOS playback experience.

**Example:**

```javascript
source={{
    uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
    metadata: {
      title: 'Custom Title',
      subtitle: 'Custom Subtitle',
      artist: 'Custom Artist',
      description: 'Custom Description',
      imageUri: 'https://pbs.twimg.com/profile_images/1498641868397191170/6qW2XkuI_400x400.png'
    }
  }}
```

#### `ad`

<PlatformsList types={['Android', 'iOS']} />

Sets the ad configuration.

**Example:**

```javascript
ad: {
  adTagUrl="https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator="
  adLanguage="fr"
}
```

See: [ads](./ads.md) for more information.

Note: You need to enable IMA SDK in the Gradle or Pod file - [enable client-side ads insertion](/installation).

#### `contentStartTime`

<PlatformsList types={['Android']} />

The start time in ms for SSAI content. This determines at what time to load the video info like resolutions. Use this only when you have an SSAI stream where the ad resolution is not the same as the content resolution.

Note: This feature only works on DASH streams.

#### `textTracksAllowChunklessPreparation`

<PlatformsList types={['Android']} />

Allow Chunkless Preparation for HLS media sources.
See: [disabling-chunkless](https://developer.android.com/media/media3/exoplayer/hls?#disabling-chunkless) in the Android documentation.

Default value: `true`.

```javascript
source={{
    uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
    textTracksAllowChunklessPreparation: false,
  }}
```

#### `bufferConfig`

<PlatformsList types={['Android']} />

Adjust the buffer settings. This prop takes an object with one or more of the properties listed below.

| Property                         | Type   | Description                                                                                                                                    |
|----------------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------|
| minBufferMs                      | number | Minimum duration of media that the player will attempt to buffer at all times, in milliseconds.                                                |
| maxBufferMs                      | number | Maximum duration of media that the player will attempt to buffer, in milliseconds.                                                             |
| bufferForPlaybackMs              | number | Duration of media that must be buffered for playback to start or resume following a user action, in milliseconds.                              |
| bufferForPlaybackAfterRebufferMs | number | Duration of media that must be buffered for playback to resume after a rebuffer, in milliseconds.                                              |
| backBufferDurationMs             | number | Duration of buffer to keep before the current position, allowing rewinding without rebuffering.                                                |
| maxHeapAllocationPercent         | number | Percentage of available heap that the video can use to buffer, between 0 and 1.                                                                |
| minBackBufferMemoryReservePercent| number | Percentage of available app memory at which during startup the back buffer will be disabled, between 0 and 1.                                  |
| minBufferMemoryReservePercent    | number | Percentage of available app memory to keep in reserve, preventing buffer usage, between 0 and 1.                                               |
| initialBitrate                   | number | Initial bitrate in bits per second (Android only). Defaults to 1_000_000. Used only at start, then ABR (Adaptive Bitrate Streaming) takes over.|
| cacheSizeMB                      | number | Cache size in MB, preventing new src requests and saving bandwidth while repeating videos, or 0 to disable. Android only.                      |
| live                             | object | Object containing another config set for live playback configuration.                                                                          |

#### `minLoadRetryCount`

<PlatformsList types={['Android']} />

Sets the minimum number of times to retry loading data before failing and reporting an error to the application. Useful for recovering from transient internet failures.

Default: `3`. Retries `3` times.

**Example:**

```javascript
source={{
  uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
  minLoadRetryCount: 5 // Retry 5 times.
}}
```

#### `textTracks`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Load one or more "sidecar" text tracks. This takes an array of objects representing each track. Each object should have the format:

> ⚠️ This feature does not work with HLS playlists (e.g., m3u8) on iOS.

| Property | Description                                                                                                   |
|----------|---------------------------------------------------------------------------------------------------------------|
| title    | Descriptive name for the track.                                                                              |
| language | 2-letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language.  |
| type     | Mime type of the track. Supports `TextTrackType.SUBRIP`, `TextTrackType.TTML`, `TextTrackType.VTT`.         |
| uri      | URL for the text track. Only tracks hosted on a web server are supported.                                   |

Note: Due to iOS limitations, sidecar text tracks are not compatible with AirPlay. If `textTracks` are specified, AirPlay support will be automatically disabled.

**Example:**

```javascript
import { TextTrackType } from 'react-native-video';

textTracks=[
  {
    title: "English CC",
    language: "en",
    type: TextTrackType.VTT, // "text/vtt"
    uri: "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt"
  },
  {
    title: "Spanish Subtitles",
    language: "es",
    type: TextTrackType.SUBRIP, // "application/x-subrip"
    uri: "https://durian.blender.org/wp-content/content/subtitles/sintel_es.srt"
  }
]
```

---

### `subtitleStyle`

<PlatformsList types={['Android', 'iOS']} />

| Property      | Platform | Description                                                                                                                                                                                        | Platforms    |
| ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| fontSize      | Android  | Adjust the font size of the subtitles. Default: font size of the device                                                                                                                            | Android      |
| paddingTop    | Android  | Adjust the top padding of the subtitles. Default: 0                                                                                                                                                | Android      |
| paddingBottom | Android  | Adjust the bottom padding of the subtitles. Default: 0                                                                                                                                             | Android      |
| paddingLeft   | Android  | Adjust the left padding of the subtitles. Default: 0                                                                                                                                               | Android      |
| paddingRight  | Android  | Adjust the right padding of the subtitles. Default: 0                                                                                                                                              | Android      |
| opacity       | Android, iOS | Adjust the visibility of subtitles with 0 hiding and 1 fully showing them. Android supports float values between 0 and 1 for varying opacity levels, whereas iOS supports only 0 or 1. Default: 1. | Android, iOS |
| subtitlesFollowVideo | Android | Boolean to adjust position of subtitles. Default: true |

**Example:**

```javascript
subtitleStyle={{ paddingBottom: 50, fontSize: 20, opacity: 0 }}
```

Note for `subtitlesFollowVideo`

`subtitlesFollowVideo` helps to determine how the subtitles are positioned.
To understand this prop, you need to understand how view management works.
The main View style passed to react-native-video is the space reserved to display the video component.
It may not match exactly the real video size.
For example, you can pass a 4:3 video view and render a 16:9 video inside.
So there is a second view, the video view.

Subtitles are managed in a third view.

* When `subtitlesFollowVideo` is set to true, the subtitle view will adapt to the video view.
If the video is displayed out of screen, the subtitles may also be displayed out of screen.
* When `subtitlesFollowVideo` is set to false, the subtitle view will adapt to the main view.
If the video is displayed out of screen, the subtitles may still remain visible within the main view.

This prop can be changed at runtime.

---

### `textTracks`

> [!WARNING]
> Deprecated, use `source.textTracks` instead. Changing text tracks will restart playback.

<PlatformsList types={['Android', 'iOS', 'visionOS']} />

Load one or more "sidecar" text tracks. This takes an array of objects representing each track. Each object should have the format:

> ⚠️ This feature does not work with HLS playlists (e.g., m3u8) on iOS.

| Property | Description |
|----------|-------------|
| title    | Descriptive name for the track |
| language | 2-letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language |
| type     | Mime type of the track (TextTrackType.SUBRIP - SubRip (.srt), TextTrackType.TTML - TTML (.ttml), TextTrackType.VTT - WebVTT (.vtt)). iOS only supports VTT, Android supports all 3. |
| uri      | URL for the text track. Currently, only tracks hosted on a web server are supported. |

On iOS, sidecar text tracks are only supported for individual files, not HLS playlists. For HLS, you should include the text tracks as part of the playlist.

Note: Due to iOS limitations, sidecar text tracks are not compatible with AirPlay. If `textTracks` are specified, AirPlay support will be automatically disabled.

**Example:**

```javascript
import { TextTrackType }, Video from 'react-native-video';

textTracks=[
  {
    title: "English CC",
    language: "en",
    type: TextTrackType.VTT, // "text/vtt"
    uri: "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt"
  },
  {
    title: "Spanish Subtitles",
    language: "es",
    type: TextTrackType.SUBRIP, // "application/x-subrip"
    uri: "https://durian.blender.org/wp-content/content/subtitles/sintel_es.srt"
  }
]
```

---

### `showNotificationControls`

<PlatformsList types={['Android', 'iOS', 'web']} />

Controls whether to show media controls in the notification area.
For Android, each Video component will have its own notification controls, whereas on iOS only one notification control will be shown for the last active Video component.

On Android, this will also allow for external controls, Google Assistant session, and other benefits of `MediaSession`.

You probably also want to set `playInBackground` to `true` to keep the video playing when the app is in the background, or `playWhenInactive` to `true` to keep the video playing when notifications or the Control Center are in front of the video.

To customize the notification controls, you can use the `metadata` property in the `source` prop.

- **false (default)** - Don't show media controls in the notification area.
- **true** - Show media controls in the notification area.

**To test notification controls on iOS, you need to run the app on a real device, as the simulator does not support it.**

**For Android, you have to add the following code in your `AndroidManifest.xml` file:**

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
    ...

    <application>
      ...
      <service
        android:name="com.brentvatne.exoplayer.VideoPlaybackService"
        android:exported="false"
        android:foregroundServiceType="mediaPlayback">
          <intent-filter>
            <action android:name="androidx.media3.session.MediaSessionService" />
          </intent-filter>
      </service>
    </application>
</manifest>
```

---

### `useSecureView`

> [!WARNING]
> deprecated, use viewType instead

<PlatformsList types={['Android']} />

Force the output to a SurfaceView and enables the secure surface.

This will override useTextureView flag.

SurfaceView is the only one that can be labeled as secure.

- **true** - Use security
- **false (default)** - Do not use security

### `useTextureView`

> [!WARNING]
> deprecated, use viewType instead

<PlatformsList types={['Android']} />

Controls whether to output to a TextureView or SurfaceView.

SurfaceView is more efficient and provides better performance but has two limitations:

- It can't be animated, transformed or scaled
- You can't overlay multiple SurfaceViews

useTextureView can only be set at the same time you're setting the source.

- **true (default)** - Use a TextureView
- **false** - Use a SurfaceView

### `viewType`

<PlatformsList types={['Android']} />

Allows explicitly specifying the view type.
This flag replaces `useSecureView` and `useTextureView` fields.
There are 3 available values:
- 'textureView': The video is rendered in a texture view. It allows mapping the view on a texture (useful for 3D).
DRM playback is not supported on textureView. If the DRM prop is provided, the surface will be transformed into a SurfaceView.
- 'surfaceView' (default): The video is rendered in a surface, taking fewer resources to render.
- 'secureView': The video is rendered in a surface that prevents screenshots from being taken.

### `volume`

<PlatformsList types={['All']} />

Adjust the volume.

- **1.0 (default)** - Play at full volume
- **0.0** - Mute the audio
- **Other values** - Reduce volume

### `cmcd`

<PlatformsList types={['Android']} />

Configure CMCD (Common Media Client Data) parameters. CMCD is a standard for conveying client-side metrics and capabilities to servers, which can help improve streaming quality and performance.

For detailed information about CMCD, please refer to the [CTA-5004 Final Specification](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).

- **false (default)** - Don't use CMCD
- **true** - Use default CMCD configuration
- **object** - Use custom CMCD configuration

When providing an object, you can configure the following properties:

| Property    | Type        | Description                                    |
|------------|------------|------------------------------------------------|
| `mode`     | `CmcdMode` | The mode for sending CMCD data               |
| `request`  | `CmcdData` | Custom key-value pairs for the request object |
| `session`  | `CmcdData` | Custom key-value pairs for the session object |
| `object`   | `CmcdData` | Custom key-value pairs for the object metadata |
| `status`   | `CmcdData` | Custom key-value pairs for the status information |

Note: The `mode` property defaults to `CmcdMode.MODE_QUERY_PARAMETER` if not specified.

#### `CmcdMode`
CmcdMode is an enum that defines how CMCD data should be sent:
- `CmcdMode.MODE_REQUEST_HEADER` (0) - Send CMCD data in the HTTP request headers.
- `CmcdMode.MODE_QUERY_PARAMETER` (1) - Send CMCD data as query parameters in the URL.

#### `CmcdData`
CmcdData is a type representing custom key-value pairs for CMCD data. It's defined as:

```typescript
type CmcdData = Record<`${string}-${string}`, string | number>;
```

Custom key names MUST include a hyphenated prefix to prevent namespace collisions. It's recommended to use a reverse-DNS syntax for custom prefixes.

**Example:**

```javascript
<Video
  source={{
    uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
    cmcd: {
      mode: CmcdMode.MODE_QUERY_PARAMETER,
      request: {
        'com-custom-key': 'custom-value'
      },
      session: {
        sid: 'session-id'
      },
      object: {
        br: '3000',
        d: '4000'
      },
      status: {
        rtp: '1200'
      }
    }
  }}
  // or other video props
/>
```
